use serde::{Deserialize, Deserializer, Serialize};
use utoipa::{IntoParams, ToSchema};
use validator::Validate;

use crate::data::{dto::user_dto::UserInfoResponse, model::user::User};

// 定义手机号正则表达式常量
lazy_static::lazy_static! {
    static ref PHONE_REGEX: regex::Regex = regex::Regex::new(r"^1[3-9]\d{9}$").unwrap();
}

/// 将字符串转换为大写形式。
/// 功能：自定义Serde反序列化函数，用于将反序列化得到的字符串转换为大写形式
/// 参数：
/// - 'de: 生命周期参数，指定反序列化器读取数据的生命周期
/// - D: 泛型参数，约束为实现了Deserializer<'de> trait的类型，代表反序列化器
fn uppercase<'de, D>(deserializer: D) -> Result<String, D::Error>
where 
    D: Deserializer<'de> // 泛型约束：D必须实现Serde的Deserializer trait，且生命周期与'de匹配
{
    // 第一步：使用String的默认反序列化方法从反序列化器中读取字符串
    // ? 操作符用于传播可能的反序列化错误（若失败则直接返回Err）
    let s = String::deserialize(deserializer)?;

    // 第二步：将获取到的字符串转换为大写，并包装成Ok返回
    Ok(s.to_uppercase())    
}

/// 用户注册请求参数
#[derive(Debug, Deserialize, Validate, ToSchema)]
pub struct RegisterRequest {
    /// 手机号
    #[schema(example = "138888888")]
    #[validate(regex(path = "*PHONE_REGEX", message = "手机号格式错误"))]
    pub phone: String,

    /// 密码
    #[schema(example = "admin@1234")]
    #[validate(length(min = 8, message = "密码不能小于8位"))]
    pub password: String,

    /// 名称
    #[schema(example = "张无忌")]
    #[validate(length(min = 2, message = "名称必须大于2个字符"))]
    pub name: String
}

#[derive(Debug, Serialize, ToSchema)]
pub struct AuthResponse {
    /// 权限令牌
    #[schema(example = "ub0F1m7RT8OkZmiucX8VXOl7xkI9FdbsVv0iQ8MSLmHpthikmf9Xa")]
    pub token: String,

    /// 用户ID
    #[schema(example = "1")]
    pub user_id: i64,

    /// 名称
    #[schema(example = "张无忌")]
    pub name: String,

    /// 手机号
    #[schema(example = "138888888")]
    pub phone: String,

    // /// 角色
    // #[schema(example = "USER")]
    // pub roles: Vec<String>
}

/// 登录请求参数
#[derive(Debug, Deserialize, Validate, ToSchema)]
pub struct LoginRequest {
    /// 用户名
    #[schema(example = "Super")]
    #[validate(length(min = 1, message = "用户名不能为空"))]
    pub username: String,

    /// 密码
    #[schema(example = "123456")]
    #[validate(length(min = 1, message = "密码不能为空"))]
    pub password: String
}

/// 登录返回参数
#[derive(Debug, Serialize, ToSchema)]
pub struct LoginResponse {
    /// 权限令牌
    pub token: String,

    /// 刷新令牌
    pub refresh_token: String,

    /// 用户信息
    pub user_info: UserInfoResponse
}

/// 新增角色请求参数
#[derive(Debug, Deserialize, ToSchema)]
pub struct AddRoleRequest {
    /// 角色名称
    #[schema(example = "客服")]
    pub name: String,

    /// 角色编码
    #[schema(example = "R_OPS")]
    #[serde(deserialize_with = "uppercase")]
    pub code: String,

    /// 角色描述
    #[schema(example = "拥有系统普通权限")]
    pub description: String,

    /// 是否启用
    #[schema(example = "true")]
    pub enabled: bool
}

/// 角色分页列表请求参数
#[derive(Debug, Deserialize, IntoParams)]
#[into_params(parameter_in = Query)]
pub struct RolePageRequest {
    /// 当前页码（从1开始）
    #[param(example = 1)]
    pub current: i32,

    /// 每页条数（默认20）
    #[param(example = 20)]
    pub size: i32,

    /// 角色名称
    // #[param(example = "客服")]
    pub name: Option<String>,
}